package com.weifly.weistock.trade.monitor.impl;

import com.weifly.weistock.core.monitor.AbstractMonitorService;
import com.weifly.weistock.trade.config.AccountConfigDto;
import com.weifly.weistock.trade.config.AllStockConfig;
import com.weifly.weistock.trade.config.StockConfigDto;
import com.weifly.weistock.trade.config.StockConfigService;
import com.weifly.weistock.trade.bo.StockMonitorBO;
import com.weifly.weistock.trade.dto.OrderDTO;
import com.weifly.weistock.trade.dto.GridStatusDTO;
import com.weifly.weistock.trade.dto.StockDTO;
import com.weifly.weistock.trade.trade.StockOrderInfo;
import com.weifly.weistock.trade.monitor.StockMonitorService;
import com.weifly.weistock.trade.trade.StockTradeService;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 股票监听服务实现
 *
 * @author weifly
 * @since 2018/10/31
 */
public class StockMonitorServiceImpl extends AbstractMonitorService implements StockMonitorService {

    private StockConfigService stockConfigService;
    private StockTradeService stockTradeService;
    private AccountConfigDto accountConfig; // 股票账号
    private List<StockMonitorBO> stockList = new ArrayList<>(); // 股票监控列表

    public void setStockConfigService(StockConfigService stockConfigService) {
        this.stockConfigService = stockConfigService;
    }

    public void setStockTradeService(StockTradeService stockTradeService) {
        this.stockTradeService = stockTradeService;
    }

    @Override
    public synchronized void updateAccountConfig(AccountConfigDto accountConfig, boolean save) {
        this.accountConfig = accountConfig;
        if (save) {
            this.saveConfigInner();
        }
        this.stockTradeService.logoff();
    }

    @Override
    public synchronized AccountConfigDto getAccountConfig() {
        return this.accountConfig;
    }

    @Override
    public void updateStockConfigList(List<StockConfigDto> stockConfigList, boolean save) {
        this.stockList.clear();
        if(stockConfigList!=null){
            for(StockConfigDto stockConfig : stockConfigList){
                StockMonitorBO monitorDto = new StockMonitorBO();
                monitorDto.setStockConfig(stockConfig);
                this.stockList.add(monitorDto);
            }
        }
        if(save){
            this.saveConfigInner();
        }
    }

    public synchronized void updateStockConfig(StockConfigDto stockConfig) {
        int targetIdx = -1;
        for(int i=0;i<this.stockList.size();i++){
            if(this.stockList.get(i).getStockConfig().getStockCode().equals(stockConfig.getStockCode())){
                targetIdx = i;
                StockMonitorBO monitorDto = new StockMonitorBO();
                monitorDto.setStockConfig(stockConfig);
                this.stockList.set(i, monitorDto);
                break;
            }
        }
        if(targetIdx==-1){
            StockMonitorBO monitorDto = new StockMonitorBO();
            monitorDto.setStockConfig(stockConfig);
            this.stockList.add(monitorDto);
        }

        this.saveConfigInner();
    }

    @Override
    public synchronized void clearStockMonitorInfo() {
        for(StockMonitorBO stockInfo : this.stockList){
            stockInfo.setNewestPrice(null);
            stockInfo.setNewestPriceUpdateTime(null);
            stockInfo.getPriceList().clear();
            stockInfo.setBuyOrderInfo(null);
            stockInfo.setBuyOrderUpdateTime(null);
            stockInfo.setSellOrderInfo(null);
            stockInfo.setSellOrderUpdateTime(null);
        }
    }

    public synchronized List<StockMonitorBO> getStockList() {
        List<StockMonitorBO> allStocks = new ArrayList<>();
        allStocks.addAll(this.stockList);
        return allStocks;
    }

    public synchronized GridStatusDTO calcMonitorInfo() {
        SimpleDateFormat timeSdf = new SimpleDateFormat("HH:mm:ss");
        GridStatusDTO statusDTO = new GridStatusDTO();
        statusDTO.setStatus(this.status);
        statusDTO.setDate(this.date);
        statusDTO.setTime(this.time);

        List<StockDTO> dataList = new ArrayList<>();
        for(StockMonitorBO stockInfo : this.stockList){
            StockConfigDto stockConfig = stockInfo.getStockConfig();
            StockDTO dataInfo = new StockDTO();
            dataInfo.setStockCode(stockConfig.getStockCode());
            dataInfo.setStockName(stockConfig.getStockName());
            if(stockInfo.getNewestPrice()!=null){
                dataInfo.setNewestPrice(stockInfo.getNewestPrice());
            }
            if(stockConfig.getBasePrice()!=null){
                dataInfo.setBasePrice(stockConfig.getBasePrice());
            }
            if(stockConfig.getLastOperation()!=null){
                dataInfo.setLastOperation(stockConfig.getLastOperation().name());
            }
            // 买入委托
            if(stockInfo.getBuyOrderInfo()!=null){
                OrderDTO buyInfo = new OrderDTO();
                StockOrderInfo orderInfo = stockInfo.getBuyOrderInfo();
                buyInfo.setOrderNumber(orderInfo.getOrderNumber());
                buyInfo.setEntrustPrice(orderInfo.getEntrustPrice());
                buyInfo.setOrderTime(timeSdf.format(new Date(orderInfo.getOrderTime())));
                dataInfo.setBuyInfo(buyInfo);
            }
            // 卖出委托
            if(stockInfo.getSellOrderInfo()!=null){
                OrderDTO sellInfo = new OrderDTO();
                StockOrderInfo orderInfo = stockInfo.getSellOrderInfo();
                sellInfo.setOrderNumber(orderInfo.getOrderNumber());
                sellInfo.setEntrustPrice(orderInfo.getEntrustPrice());
                sellInfo.setOrderTime(timeSdf.format(new Date(orderInfo.getOrderTime())));
                dataInfo.setSellInfo(sellInfo);
            }
            dataList.add(dataInfo);
        }
        statusDTO.setStockList(dataList);
        statusDTO.setMessageList(this.collectMessage());
        return statusDTO;
    }

    @Override
    public synchronized void saveConfig() {
        this.saveConfigInner();
    }

    private void saveConfigInner(){
        AllStockConfig allStockConfig = new AllStockConfig();
        allStockConfig.setAccountConfig(this.accountConfig);
        List<StockConfigDto> stockConfigList = new ArrayList<>();
        for(StockMonitorBO monitorDto : this.stockList){
            stockConfigList.add(monitorDto.getStockConfig());
        }
        allStockConfig.setStockConfigList(stockConfigList);
        this.stockConfigService.saveConfig(allStockConfig);
    }
}
